package com.test.test

import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.widget.ScrollView
import kotlin.math.abs

class VerticalScrollView(mContext: Context, attrs: AttributeSet?, defStyleAttr: Int): ScrollView(mContext, attrs, defStyleAttr) {
    constructor(mContext: Context, attrs: AttributeSet?): this(mContext, attrs, 0)
    constructor(mContext: Context): this(mContext,null, 0)
    //滑动触底/触顶监听
    private var onScrollEndListener: ((endFlag: Int) -> Unit)? = null
    private var interceptStartX = 0f
    private var interceptStartY = 0f
    private var maxY = 0
    companion object{
        const val flagTop = 0
        const val flagBottom = 1
    }

    fun setOnScrollEndListener(onScrollEndListener: ((endFlag: Int) -> Unit)?){
        this.onScrollEndListener = onScrollEndListener
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        //获得最大可滑动高度
        maxY = getChildAt(0).measuredHeight - measuredHeight
    }

    /**
     * 监听是否触底或触顶
     */
    override fun onScrollChanged(l: Int, t: Int, oldl: Int, oldt: Int) {
        super.onScrollChanged(l, t, oldl, oldt)
        if(scrollY == 0)
            onScrollEndListener?.invoke(flagTop)
        else if(getChildAt(0).measuredHeight == measuredHeight + scrollY)
            onScrollEndListener?.invoke(flagBottom)
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(ev: MotionEvent?): Boolean {
        when(ev?.action){
            MotionEvent.ACTION_DOWN -> {
            }
            MotionEvent.ACTION_MOVE -> {
            }
            MotionEvent.ACTION_UP -> {
            }
        }
        return super.onTouchEvent(ev)
    }

    /**
     * 控制事件分发
     */
    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        when(ev?.action){
            MotionEvent.ACTION_DOWN -> {
                //当两个VerticalScrollView嵌套时，内部的优先取得事件
                parent.requestDisallowInterceptTouchEvent(true)
            }
            MotionEvent.ACTION_MOVE -> {
                //在可滑动范围内持续获取事件
                if(scrollY in 1 until maxY)
                    parent.requestDisallowInterceptTouchEvent(true)
                else
                    //在范围外交还事件所有权
                    parent.requestDisallowInterceptTouchEvent(false)
            }
            MotionEvent.ACTION_UP -> {
                //抬起时主动交还事件
                parent.requestDisallowInterceptTouchEvent(false)
            }
        }
        return super.dispatchTouchEvent(ev)
    }

    /**
     * 控制事件拦截
     */
    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        when(ev?.action){
            MotionEvent.ACTION_DOWN -> {
                interceptStartX = ev.rawX
                interceptStartY = ev.rawY
            }
            MotionEvent.ACTION_MOVE -> {
                val deltaX = abs(ev.rawX - interceptStartX)
                val deltaY = abs(ev.rawY - interceptStartY)
                //水平滑动不拦截事件
                if(deltaX > deltaY){
                    return false
                }
            }
            MotionEvent.ACTION_UP -> {
            }
        }
        return super.onInterceptTouchEvent(ev)
    }

}